﻿using HandyControl.Tools.Extension;
using IntoCommon.Util;
using IntoStationSystem.Db;
using IntoStationSystem.Entity;
using IntoStationSystem.Enums;
using IntoStationSystem.ExDevice;
using IntoStationSystem.Global;
using IntoStationSystem.Models;
using IntoStationSystem.PLC;
using Microsoft.VisualBasic.Logging;
using Newtonsoft.Json;
using Prism.Mvvm;
using S7.Net;
using S7.Net.Types;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Markup;
using System.Xml.Linq;
using static IntoStationSystem.Global.Events;

namespace IntoStationSystem.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        #region field
        /// <summary>
        /// PLC数据缓存
        /// </summary>
        public PlcData plcData = new PlcData();
        /// <summary>
        /// 上一次生产型号
        /// </summary>
        int lastProduceModel = -1;

        /// <summary>
        /// 拍照次数
        /// </summary>
        int PhotoNum = 0;
        #endregion
        private Thread ConfigThread;
        private Thread serialPortsThread1;
        private Thread serialPortsThread2;
        private Thread serialPortsThread3;
        private Thread serialPortsThread4;
        #region property
        private IOStateViewModel IO => Locator.Instance.IOStateVM;

        private HomeViewModel home => Locator.Instance.MainPageVM;

        public Service services => Locator.Instance.Service;
        private ProductSettingViewModel proSet => Locator.Instance.ProductSettingVM;
        private ManualViewModel Manual => Locator.Instance.ManualVM;

        private PrintDev printDev = new PrintDev();
        private PhotoDev photoDev = new PhotoDev();


        /// <summary>
        /// 串口设备，创建4个
        /// </summary>
        private SerialPortDev[] serialPorts = new SerialPortDev[4];
        //{
        //    new SerialPortDev(Fields.SerialPort1, Fields.BaudRate1, Fields.SerialType1),
        //    new SerialPortDev(Fields.SerialPort2, Fields.BaudRate2, Fields.SerialType2),
        //    new SerialPortDev(Fields.SerialPort3, Fields.BaudRate3, Fields.SerialType3),
        //    new SerialPortDev(Fields.SerialPort4, Fields.BaudRate4, Fields.SerialType4),
        //};


        private bool useCfg = false;
        public bool UseCfg
        {
            get => useCfg;
            set
            {
                useCfg = value;
                RaisePropertyChanged(nameof(UseCfg));
            }
        }

        public bool IsDisposed { get; set; } = false;
        #endregion
        /// <summary>
        /// 切换照片上升沿触发器
        /// </summary>
        TrigR ShowPhotoTrig = new TrigR();
        /// <summary>
        /// 打印标签上升沿触发器
        /// </summary>
        TrigR PrintTrig = new TrigR();
        /// <summary>
        /// 允许扫码上升沿触发器
        /// </summary>
        TrigR EnableScanTrig = new TrigR();
        /// <summary>
        /// 采集数据上升沿触发器
        /// </summary>
        TrigR CollectTrig = new TrigR();
        /// <summary>
        /// 型号切换上升沿触发器
        /// </summary>
        TrigR ChangeModelTrig = new TrigR();
        /// <summary>
        /// 上一个工位参数下发上升沿触发器
        /// </summary>
        TrigR LastStationParamTrig = new TrigR();
        /// <summary>
        /// 启动风机1上升沿触发器
        /// </summary>
        TrigR StartFan1Trig = new TrigR();
        /// <summary>
        /// 停止风机1上升沿触发器
        /// </summary>
        TrigR StopFan1Trig = new TrigR();
        /// <summary>
        /// 启动风机2上升沿触发器
        /// </summary>
        TrigR StartFan2Trig = new TrigR();
        /// <summary>
        /// 停止风机2上升沿触发器
        /// </summary>
        TrigR StopFan2Trig = new TrigR();


        /// <summary>
        /// 试漏上升沿触发器
        /// </summary>
        TrigR TryLeakTrig = new TrigR();

        /// <summary>
        /// 提示信息上升沿触发器
        /// </summary>
        TrigR[] TipOnTrigs = new TrigR[32];
        /// <summary>
        /// 提示信息下降沿触发器
        /// </summary>
        TrigF[] TipOffTrigs = new TrigF[32];
        /// <summary>
        /// 警告信息上升沿触发器
        /// </summary>
        TrigR[] WarningOnTrigs = new TrigR[32];
        /// <summary>
        /// 警告信息下降沿触发器
        /// </summary>
        TrigF[] WarningOffTrigs = new TrigF[32];
        /// <summary>
        /// 报警信息上升沿触发器
        /// </summary>
        TrigR[] AlarmOnTrigs = new TrigR[128];
        /// <summary>
        /// 报警信息下降沿触发器
        /// </summary>
        TrigF[] AlarmOffTrigs = new TrigF[128];

        #region Refresh
        public MainWindowViewModel()
        {
            //DbHelper.Log("MainWindowViewModel");
            LoadConfig();
            Locator.Instance.Service.StatusChangedEvent += GetPlcData;
            ConfigThread = new Thread(new ThreadStart(Display));
            ConfigThread.IsBackground = true;
            ConfigThread.Start();
            //串口1
            serialPortsThread1 = new Thread(new ParameterizedThreadStart(CreateSerialPorts));
            serialPortsThread1.IsBackground = true;
            serialPortsThread1.Start(new object[] { Fields.SerialPort1, Fields.BaudRate1, Fields.SerialType1, 1 });
            //串口2
            serialPortsThread2 = new Thread(new ParameterizedThreadStart(CreateSerialPorts));
            serialPortsThread2.IsBackground = true;
            serialPortsThread2.Start(new object[] { Fields.SerialPort2, Fields.BaudRate2, Fields.SerialType2, 2 });
            //串口3
            serialPortsThread3 = new Thread(new ParameterizedThreadStart(CreateSerialPorts));
            serialPortsThread3.IsBackground = true;
            serialPortsThread3.Start(new object[] { Fields.SerialPort3, Fields.BaudRate3, Fields.SerialType3,3 });
            //串口4
            serialPortsThread4 = new Thread(new ParameterizedThreadStart(CreateSerialPorts));
            serialPortsThread4.IsBackground = true;
            serialPortsThread4.Start(new object[] { Fields.SerialPort4, Fields.BaudRate4, Fields.SerialType4, 4 });
            //Display();

        }

        /// <summary>
        /// 
        /// </summary>
        private void CreateSerialPorts(object obj)
        {
            object[] parameters = (object[])obj;
            string  SerialPort = (string)parameters[0];
            int BaudRate = (int)parameters[1];
            string SerialType = (string)parameters[2];
            int Num = (int)parameters[3];
            serialPorts[Num-1] = new SerialPortDev(SerialPort, BaudRate, SerialType);
           
        }


        /// <summary>
        /// 加载配置
        /// </summary>
        private void LoadConfig()
        {

            for (int i = 0; i < 128; i++)
            {
                AlarmOffTrigs[i] = new TrigF();
                AlarmOnTrigs[i] = new TrigR();
                if (i < 32)
                {
                    TipOnTrigs[i] = new TrigR();
                    TipOffTrigs[i] = new TrigF();
                    WarningOffTrigs[i] = new TrigF();
                    WarningOnTrigs[i] = new TrigR();
                }
            }
        }

        private void GetPlcData(PlcData data)
        {
            plcData = data;
        }
        /// <summary>
        /// 锁
        /// </summary>
        private object locker = new object();
        /// <summary>
        /// 界面数据刷新
        /// </summary>
        private void Display()
        {
            try
            {


                #region
                //Task.Run(() =>
                //{
                //    while (/*!IsDisposed*/true)
                //    {
                //        LoadConfig();
                //        Thread.Sleep(200);
                //        RefreshHome(plcData);
                //        RefreshIO(plcData);
                //        RefreshManual(plcData);
                //        RefreshTrigs(plcData);
                //        GetExDevData(plcData);
                //    }
                //});
                #endregion

                while (!IsDisposed)
                {
                    Thread.Sleep(200);

                    RefreshHome(plcData);
                    //DbHelper.Log("2");
                    //RefreshIO(plcData);
                    RefreshManual(plcData);

                    RefreshTrigs(plcData);

                    GetExDevData(plcData);

                }

            }
            catch (Exception ex)
            {

                HandyControl.Controls.MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 刷新各个触发器
        /// </summary>
        private void RefreshTrigs(PlcData plc)
        {
            //允许扫码
            EnableScanTrig.Clk = plc.Collection[5] == 1;
            if (EnableScanTrig.Q)
            {
                //DbHelper.LogTip("允许扫码");
                home.EnablScan = true;
                DbHelper.Log("允许扫码");
            }

            //采集数据
            try
            {
                CollectTrig.Clk = plc.Collection[1] == 1;
                //出发采集后，进行采集，同时写入采集完成标志给PLC
                if (CollectTrig.Q)
                {
                    int result = -1;
                    ProduceData product = new ProduceData();
                    ProduceData product1 = null;
                    ProduceData product2 = null;
                    
                 
                    product.TrayId = plc.CraftId.Trim();
                    product.ProductMode = home.ProModel;
                    int len = home.PartCodes.Count;
                    int len1 = proSet.EnableScans.Count;
                    var _collectionDatas =services.plc.ReadBytes(DataType.DataBlock, Fields.GetDbAddr, 0, Fields.GetDataLen);
                    var _datas = services.plc.ReadBytes(DataType.DataBlock, Fields.DbAddr, 0, Fields.DataLen);
                    if (Fields.Station == "JZ" || Fields.Station == "GP12")
                    {

                        string partCode = len > 0 ? home.PartCodes[0] : string.Empty;
                        product = DbHelper.GetCodeStationData(partCode);

                        

                    }
                    if (Fields.Station == "OP10"|| Fields.Station == "OP40")
                    {
                        //判断载具号是否重复（10工位或者40工位都可以当首工位，首工位不允许载具id重复）
                        product1 = DbHelper.GetStationData(product.TrayId);
                        //返修上线判断40工位风扇码是否在数据库存在
                        string partCode = len > 0 ? home.PartCodes[0] : string.Empty;
                        product2 = DbHelper.GetCodeStationData(partCode);
                    }
                    
                    if (product == null || (len != len1 && len1 != 0)||(Fields.Station == "OP40"&& product2==null))
                    {
                        result = 0;
                        HandyControl.Controls.MessageBox.Show("零件码不存在！请检查！");
                       
                    }
                    else if (product1 != null || product.TrayId.Contains("0000000000")||string.IsNullOrEmpty(product.TrayId))
                    {
                        result = 0;
                       
                        HandyControl.Controls.MessageBox.Show("载具ID在数据库重复！请回原重新做！载具ID为：" + product.TrayId);
                       
                    }
                    else
                    {

                        switch (Fields.Station)
                        {
                            case "OP10":
                                product.OP10Result = GetResult(services.Map("GetBytes", _collectionDatas)[0]);    //GetResult(plc.GetBytes[0]);
                                product.OP10PartCode1 = len > 0 ? home.PartCodes[0] : string.Empty;
                                product.OP10PartCode2 = len > 1 ? home.PartCodes[1] : string.Empty;
                                product.OP10PartCode3 = len > 2 ? home.PartCodes[2] : string.Empty;
                                product.OP10PartCode4 = len > 3 ? home.PartCodes[3] : string.Empty;

                                product.OP10PartCode1 = len1 > 0 ? product.OP10PartCode1 : "NA";
                                product.OP10PartCode2 = len1 > 1 ? product.OP10PartCode2 : "NA";
                                product.OP10PartCode3 = len1 > 2 ? product.OP10PartCode3 : "NA";
                                product.OP10PartCode4 = len1 > 3 ? product.OP10PartCode4 : "NA";

                                product.OP10Angle1 = Math.Round(plc.GetFloats[1], 2);
                                product.OP10Torque1 = Math.Round(plc.GetFloats[0], 2);
                                product.OP10Angle2 = Math.Round(plc.GetFloats[4], 2);
                                product.OP10Torque2 = Math.Round(plc.GetFloats[3], 2);
                                product.OP10Angle3 = Math.Round(plc.GetFloats[7], 2);
                                product.OP10Torque3 = Math.Round(plc.GetFloats[6], 2);
                                product.OP10Angle4 = Math.Round(plc.GetFloats[10], 2);
                                product.OP10Torque4 = Math.Round(plc.GetFloats[9], 2);
                                break;
                            case "OP20":
                                product.OP20Result = GetResult(services.Map("GetBytes", _collectionDatas)[0]);//GetResult(plc.GetBytes[0]);
                                product.OP20PartCode1 = len > 0 ? home.PartCodes[0] : string.Empty;
                                product.OP20PartCode2 = len > 1 ? home.PartCodes[1] : string.Empty;
                                product.OP20PartCode3 = len > 2 ? home.PartCodes[2] : string.Empty;
                                product.OP20PartCode4 = len > 3 ? home.PartCodes[3] : string.Empty;
                                product.OP20PartCode1 = len1 > 0 ? product.OP20PartCode1 : "NA";
                                product.OP20PartCode2 = len1 > 1 ? product.OP20PartCode2 : "NA";
                                product.OP20PartCode3 = len1 > 2 ? product.OP20PartCode3 : "NA";
                                product.OP20PartCode4 = len1 > 3 ? product.OP20PartCode4 : "NA";
                                product.OP20Angle1 = Math.Round(plc.GetFloats[1], 2);
                                product.OP20Torque1 = Math.Round(plc.GetFloats[0], 2);
                                product.OP20Angle2 = Math.Round(plc.GetFloats[4], 2);
                                product.OP20Torque2 = Math.Round(plc.GetFloats[3], 2);
                                product.OP20Angle3 = Math.Round(plc.GetFloats[7], 2);
                                product.OP20Torque3 = Math.Round(plc.GetFloats[6], 2);
                                product.OP20Angle4 = Math.Round(plc.GetFloats[10], 2);
                                product.OP20Torque4 = Math.Round(plc.GetFloats[9], 2);
                                product.OP20Image = Path.GetFileName(home.PhotoUrl1);
                                break;
                            case "OP30":
                                product.OP30Result = GetResult(services.Map("GetBytes", _collectionDatas)[0]);// GetResult(plc.GetBytes[0]);
                                product.OP30PartCode1 = len > 0 ? home.PartCodes[0] : string.Empty;
                                product.OP30PartCode2 = len > 1 ? home.PartCodes[1] : string.Empty;
                                product.OP30PartCode3 = len > 2 ? home.PartCodes[2] : string.Empty;
                                product.OP30PartCode4 = len > 3 ? home.PartCodes[3] : string.Empty;
                                product.OP30PartCode1 = len1 > 0 ? product.OP30PartCode1 : "NA";
                                product.OP30PartCode2 = len1 > 1 ? product.OP30PartCode2 : "NA";
                                product.OP30PartCode3 = len1 > 2 ? product.OP30PartCode3 : "NA";
                                product.OP30PartCode4 = len1 > 3 ? product.OP30PartCode4 : "NA";
                                product.OP30Angle1 = Math.Round(plc.GetFloats[1], 2);
                                product.OP30Torque1 = Math.Round(plc.GetFloats[0], 2);
                                product.OP30Angle2 = Math.Round(plc.GetFloats[4], 2);
                                product.OP30Torque2 = Math.Round(plc.GetFloats[3], 2);
                                product.OP30Angle3 = Math.Round(plc.GetFloats[7], 2);
                                product.OP30Torque3 = Math.Round(plc.GetFloats[6], 2);
                                product.OP30Angle4 = Math.Round(plc.GetFloats[10], 2);
                                product.OP30Torque4 = Math.Round(plc.GetFloats[9], 2);
                                break;
                            case "OP40":

                                //获取配方
                                var pros = DbHelper.GetConfig<ProductModel>(home.ProModel).ToList();
                                int num = 0;
                                for (int i = 0; i < pros[0].RealValue; i++)
                                {
                                    var obj=product.GetType().GetProperties().Where(p => p.Name == "OP10PartCode" + (i + 1)).ToList();
                                    obj[0].SetValue(product, home.PartCodes[num]);
                                    num++;
                                }
                                for (int i = 0; i < pros[1].RealValue; i++)
                                {
                                    var obj = product.GetType().GetProperties().Where(p => p.Name == "OP20PartCode" + (i + 1)).ToList();
                                    obj[0].SetValue(product, home.PartCodes[num]);
                                    num++;
                                }
                                for (int i = 0; i < pros[2].RealValue; i++)
                                {
                                    var obj = product.GetType().GetProperties().Where(p => p.Name == "OP30PartCode" + (i + 1)).ToList();
                                    obj[0].SetValue(product, home.PartCodes[num]);
                                    num++;
                                }


                                product.OP10PartCode1 = !string.IsNullOrEmpty(product.OP10PartCode1) ? product.OP10PartCode1 :"NA";
                                product.OP10PartCode2 = !string.IsNullOrEmpty(product.OP10PartCode2) ? product.OP10PartCode2 : "NA";
                                product.OP10PartCode3 = !string.IsNullOrEmpty(product.OP10PartCode3) ? product.OP10PartCode3 : "NA";
                                product.OP10PartCode4 = !string.IsNullOrEmpty(product.OP10PartCode4) ? product.OP10PartCode4 : "NA";
                                product.OP10Angle1 = product2.OP10Angle1;
                                product.OP10Torque1 = product2.OP10Torque1;
                                product.OP10Angle2 = product2.OP10Angle2;
                                product.OP10Torque2 = product2.OP10Torque2;
                                product.OP10Angle3 = product2.OP10Angle3;
                                product.OP10Torque3 = product2.OP10Torque3;
                                product.OP10Angle4 = product2.OP10Angle4;
                                product.OP10Torque4 = product2.OP10Torque4;
                                product.OP20PartCode1 = !string.IsNullOrEmpty(product.OP20PartCode1) ? product.OP20PartCode1 : "NA";
                                product.OP20PartCode2 = !string.IsNullOrEmpty(product.OP20PartCode2) ? product.OP20PartCode2 : "NA";
                                product.OP20PartCode3 = !string.IsNullOrEmpty(product.OP20PartCode3) ? product.OP20PartCode3 : "NA";
                                product.OP20PartCode4 = !string.IsNullOrEmpty(product.OP20PartCode4) ? product.OP20PartCode4 : "NA";
                                product.OP20Angle1 = product2.OP20Angle1;
                                product.OP20Torque1 = product2.OP20Torque1;
                                product.OP20Angle2 = product2.OP20Angle2;
                                product.OP20Torque2 = product2.OP20Torque2;
                                product.OP20Angle3 = product2.OP20Angle3;
                                product.OP20Torque3 = product2.OP20Torque3;
                                product.OP20Angle4 = product2.OP20Angle4;
                                product.OP20Torque4 = product2.OP20Torque4;
                                product.OP20Image   = product2.OP20Image;
                                product.OP30PartCode1 = !string.IsNullOrEmpty(product.OP30PartCode1) ? product.OP30PartCode1 : "NA";
                                product.OP30PartCode2 = !string.IsNullOrEmpty(product.OP30PartCode2) ? product.OP30PartCode2 : "NA";
                                product.OP30PartCode3 = !string.IsNullOrEmpty(product.OP30PartCode3) ? product.OP30PartCode3 : "NA";
                                product.OP30PartCode4 = !string.IsNullOrEmpty(product.OP30PartCode4) ? product.OP30PartCode4 : "NA";
                                product.OP30Angle1 = product2.OP30Angle1;
                                product.OP30Torque1 = product2.OP30Torque1;
                                product.OP30Angle2 = product2.OP30Angle2;
                                product.OP30Torque2 = product2.OP30Torque2;
                                product.OP30Angle3 = product2.OP30Angle3;
                                product.OP30Torque3 = product2.OP30Torque3;
                                product.OP30Angle4 = product2.OP30Angle4;
                                product.OP30Torque4 = product2.OP30Torque4;
                                product.IsRepair = true;
                                product.OP10Result = "OK";
                                product.OP20Result = "OK";
                                product.OP30Result = "OK";
                                break;
                            case "OP50":
                                //电检
                                product.OP50Voltage1 = Math.Round(plc.GetFloats[0], 2);
                                product.OP50Current1 = Math.Round(plc.GetFloats[1], 2);
                                product.OP50Frequency1 = Math.Round(plc.GetFloats[2], 2);
                                product.OP50Duty1 = Math.Round(plc.GetFloats[3], 2);
                                product.OP50FanResult1 = GetResult((int)plc.GetFloats[4]);
                                product.OP50Voltage2 = Math.Round(plc.GetFloats[5], 2);
                                product.OP50Current2 = Math.Round(plc.GetFloats[6], 2);
                                product.OP50Frequency2 = Math.Round(plc.GetFloats[7], 2);
                                product.OP50Duty2 = Math.Round(plc.GetFloats[8], 2);
                                product.OP50FanResult2 = GetResult((int)plc.GetFloats[9]);
                                //气检
                                product.OP50Presure = Math.Round(plc.GetFloats[10], 2);
                                product.OP50Leakage = Math.Round(plc.GetFloats[11], 2);
                                product.OP50GasResult = GetResult((int)plc.GetFloats[12]);
                                product.OP50Result = GetResult(services.Map("GetBytes", _collectionDatas)[0]); //GetResult(plc.GetBytes[0]);
                                break;
                            case "OP60":
                                product.OP60Result = GetResult(services.Map("GetBytes", _collectionDatas)[0]); //GetResult(plc.GetBytes[0]);
                                product.OP60Code = len > 0 ? home.PartCodes[0] : string.Empty;
                                product.OP60Picture = home.ImageName;
                                break;
                            case "GP12": //GP12工位
                                product.GP12Result = GetResult(services.Map("GetBytes", _collectionDatas)[0]);// GetResult(plc.GetBytes[0]);
                                product.GP12Code = len > 1 ? home.PartCodes[1] : string.Empty;
                                product.GP12Image1 = Path.GetFileName(home.PhotoUrl1);
                                product.GP12Image2 = Path.GetFileName(home.PhotoUrl2);
                                break;
                            case "JZ": // 减震工位
                                product.JZResult = GetResult(services.Map("GetBytes", _collectionDatas)[0]);//GetResult(plc.GetBytes[0]);
                                product.JZImage1 = Path.GetFileName(home.PhotoUrl1);
                                product.JZImage2 = Path.GetFileName(home.PhotoUrl2);
                                break;
                        }
                        //product.LastStationData = JsonConvert.SerializeObject(plc.Reads);
                        product.LastStationData = JsonConvert.SerializeObject(services.Map("Reads", _datas));



                        product.DateTime = System.DateTime.Now;
                        UpdateTotalResult(product);

                            //写入远程

                            result = DbHelper.LogProductRemote(product, Fields.Station);
                            if (result <= 0)
                            {
                                //写入本地
                                result = DbHelper.LogProductLocal(product, Fields.Station);
                            }
                     
                    }
                    if (result <= 0)
                    {
                        DbHelper.LogAlarm("采集数据失败");
                    }
                    else
                    {
                        //回复PLC采集完成
                        Locator.Instance.Service.ResponseCollection(1);
                        //重置采集数据
                        ResetCollection();
                        DbHelper.LogTip("重置采集数据");
                        if (Fields.Station == "OP20")
                        {
                            //清空图片
                            home.PhotoUrl1 = "";
                            home.PhotoUrl2 = "";
                        }
                    }
                }
            }
            catch
            {
                DbHelper.LogTip("数据采集失败");
            }

            //plc消息提示与自复位
            for (int i = 0; i < 128; i++)
            {
                AlarmOffTrigs[i].Clk = plc.Alarm[i];
                if (AlarmOffTrigs[i].Q) home.PlcMsgChenged(i, Enums.MsgType.Alarm, false);
                AlarmOnTrigs[i].Clk = plc.Alarm[i];
                if (AlarmOnTrigs[i].Q) home.PlcMsgChenged(i, Enums.MsgType.Alarm, true);
                if (i < 32)
                {
                    TipOnTrigs[i].Clk = plc.Prompt[i];
                    if (TipOnTrigs[i].Q) home.PlcMsgChenged(i, Enums.MsgType.Tip, true);
                    TipOffTrigs[i].Clk = plc.Prompt[i];
                    if (TipOffTrigs[i].Q) home.PlcMsgChenged(i, Enums.MsgType.Tip, false);
                    WarningOffTrigs[i].Clk = plc.Waring[i];
                    if (WarningOffTrigs[i].Q) home.PlcMsgChenged(i, Enums.MsgType.Warning, false);
                    WarningOnTrigs[i].Clk = plc.Waring[i];
                    if (WarningOnTrigs[i].Q) home.PlcMsgChenged(i, Enums.MsgType.Warning, true);
                }
            }
            StartFan1Trig.Clk = plc.Groups[0].Read[0];//风机1启动
            if (StartFan1Trig.Q)
            {
                if (!serialPorts[1].IsOpen)
                {
                    serialPorts[1].Open(Fields.SerialPort2, Fields.BaudRate2);
                }
                EventRepository.EventAggregator.GetEvent<StartFan1Event>().Publish();
                
                  
                
            }

            StartFan2Trig.Clk = plc.Groups[1].Read[0];//风机2启动
            if (StartFan2Trig.Q)
            {
                if (!serialPorts[2].IsOpen)
                {
                    serialPorts[2].Open(Fields.SerialPort3, Fields.BaudRate3);
                }
                 EventRepository.EventAggregator.GetEvent<StartFan2Event>().Publish();
                
                   
              
            }

            StopFan1Trig.Clk = plc.Groups[0].Read[1];//风机1停止
            if (StopFan1Trig.Q)
            {
                EventRepository.EventAggregator.GetEvent<StopFan1Event>().Publish();
            }

            StopFan2Trig.Clk = plc.Groups[1].Read[1];//风机2停止
            if (StopFan2Trig.Q)
            {
                EventRepository.EventAggregator.GetEvent<StopFan2Event>().Publish();
            }

            //上一个工位参数下发
            LastStationParamTrig.Clk = plc.Collection[0] == 1;
            if (LastStationParamTrig.Q)
            {
                try
                {


                    DbHelper.LogTip("请求下发工位参数");

                    //下发工位参数，完成后回复2
                    string lastInfo = string.Empty;
                    if (Fields.Station != "JZ" && Fields.Station != "GP12")
                    {

                        lastInfo = DbHelper.GetLastStationPara(plc.CraftId.Trim(), false);

                    }
                    else
                    {
                        int len = home.PartCodes.Count;
                        string partCode = len > 0 ? home.PartCodes[0] : string.Empty;
                        lastInfo = DbHelper.GetLastStationPara(partCode, true);
                    }
                    DbHelper.LogTip(lastInfo);
                    var sendData = JsonConvert.DeserializeObject<byte[]>(lastInfo);
                    Locator.Instance.Service.WriteData(Fields.Map["Writes"].First, sendData);
                    Locator.Instance.Service.ResponseCollection(0);
                    DbHelper.LogTip("工位参数下发完成");
                }
                catch (Exception ex)
                {

                    DbHelper.LogTip("下发工位参数报错！" + ex.Message);
                }
            }
            //拍照
            ShowPhotoTrig.Clk = plc.Collection[3] == 1;

            if (ShowPhotoTrig.Q)
            {
                try
                {


                    if (IsShowPhoto)
                    {
                        IsShowPhoto = false;
                        DbHelper.LogTip("请求拍照显示");

                        photoDev.ProModel = home.ProModel;
                        photoDev.CraftId = home.HomeModel.CraftId;
                        int len = home.PartCodes.Count;
                        photoDev.PartCode = len > 0 ? home.PartCodes[0] : string.Empty;
                        photoDev.ShowPhoto();
                        home.PhotoUrl2 = photoDev.PhotoUrl2;
                        home.PhotoUrl1 = photoDev.PhotoUrl1;

                        IsShowPhoto = true;
                    }
                }
                catch (Exception)
                {

                    IsShowPhoto = true;
                }

            }
            //打印标签
            PrintTrig.Clk = plc.Collection[4] == 1;
            if (PrintTrig.Q)
            {
                DbHelper.LogTip("请求打印标签");
                printDev.ProModel = home.ProModel;
                printDev.PrintLabels();

            }
            //切换型号
            ChangeModelTrig.Clk = plc.LocalModelId != lastProduceModel;
            if (ChangeModelTrig.Q)
            {
                lastProduceModel = plc.LocalModelId;
                DbHelper.LogTip("请求切换产品型号");
                RefreshHome(plcData);
                if (home.ProModel != null)
                {
                    EventRepository.EventAggregator.GetEvent<MesChangeRecipeEvent>().Publish(home.ProModel.Trim());
                }

            }
        }

        bool IsPanduan = true;

        //是否照片拍照完成
        public bool IsShowPhoto = true;


        private static void Log(string message)
        {
            using (StreamWriter writer = new StreamWriter("D:/messge.txt", append: true))
            {
                string logMessage = $"{System.DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}";
                writer.WriteLine(logMessage);
            }
        }



        private void UpdateTotalResult(ProduceData pro)
        {
            if (pro.OP10Result == "NG" ||
                pro.OP20Result == "NG" ||
                pro.OP30Result == "NG" ||
                pro.OP50Result == "NG" ||
                pro.OP60Result == "NG" ||
                pro.JZResult == "NG" ||
                pro.GP12Result == "NG")
            {
                pro.Result = "NG";
            }
            else if (string.IsNullOrEmpty(pro.OP10Result) ||
                     string.IsNullOrEmpty(pro.OP20Result) ||
                     string.IsNullOrEmpty(pro.OP30Result) ||
                     string.IsNullOrEmpty(pro.OP50Result) ||
                     string.IsNullOrEmpty(pro.OP60Result) ||
                     string.IsNullOrEmpty(pro.GP12Result) ||
                     string.IsNullOrEmpty(pro.JZResult))
            {
                pro.Result = string.Empty;
            }
            else
            {
                pro.Result = "OK";
            }
        }

        string PastProModel = string.Empty;

        /// <summary>
        /// 刷新主界面数据
        /// </summary>
        /// <param name="plc"></param>
        private void RefreshHome(PlcData plc)
        {
            home.IsConnected = Locator.Instance.Service.IsConnected;
            home.HomeModel.CraftId = plc.CraftId;
            home.HomeModel.PageIDFeedback = (ushort)plc.PageIdFeedBack;
            home.HomeModel.SysOK = plc.SysBit[0];
            home.HomeModel.DebugMode = plc.SysBit[1];
            home.HomeModel.AutoMode = plc.SysBit[2];
            home.HomeModel.PauseMode = plc.SysBit[3];
            home.HomeModel.StopMode = plc.SysBit[4];
            home.HomeModel.RstMode = plc.SysBit[5];
            home.HomeModel.HomeMode = plc.SysBit[6];
            home.HomeModel.EStopMode = plc.SysBit[7];
            home.HomeModel.SysSafe = plc.SysBit[8];
            home.HomeModel.HomePos = plc.SysBit[9];
            home.HomeModel.AutoEnd = plc.SysBit[10];
            home.HomeModel.HasTip = plc.SysBit[13];
            home.HomeModel.HasWarning = plc.SysBit[14];
            home.HomeModel.HasAlarm = plc.SysBit[15];
            //当前生产型号需要对应的触发器
            home.HomeModel.ProduceModel = (ushort)plc.LocalModelId;
            home.HomeModel.ProduceCount = plc.ProduceCount;
            home.HomeModel.OKCount = plc.OkCount;
            home.HomeModel.NGCount = plc.NgCount;
            home.HomeModel.BeatTime = plc.BeatTime;
            home.HomeModel.RunTime = plc.RunTime;
            home.HomeModel.ForceNGMode = plc.SetButton[2];
            home.HomeModel.EmptyTrayMode = plc.SetButton[3];
            home.HomeModel.Mute = plc.SetButton[6];
            home.HomeModel.LocalRemote = plc.SetButton[0];

            if (home.HomeModel.LocalRemote && IsPanduan)
            {
                IsPanduan = false;
                home.BtnMes = ButtonStatus.CHECKED;
            }
            else if (!home.HomeModel.LocalRemote && IsPanduan)
            {

                IsPanduan = false;
                home.BtnMes = ButtonStatus.NORMAL;
            }


            home.ProStepIndex = plc.Step;
            home.HomeModel.Quality = plc.GetBytes[0];


            if (home.HomeModel.Quality == 0)
            {
                home.IsShow = "Collapsed";


            }
            else
            {
                if (home.HomeModel.Quality == 2)
                {
                    home.HomeModel.Quality = 0;
                }

                home.IsShow = "Visible";
                //home.QualityBtn.Visibility = Visibility.Visible;
            }
            //DbHelper.LogTip("1.2");
            //加载扭矩
            #region  加载扭矩
            home.Angle1 = Math.Round(plc.GetFloats[1], 2);
            home.Torque1 = Math.Round(plc.GetFloats[0], 2);
            home.Angle2 = Math.Round(plc.GetFloats[4], 2);
            home.Torque2 = Math.Round(plc.GetFloats[3], 2);
            if (home.Angle1 > 0)
            {
                home.Angle1Result = "OK";

            }
            if (home.Angle2 > 0)
            {
                home.Angle2Result = "OK";

            }
            if (home.Torque1 > 0)
            {
                home.Torque1Result = "OK";

            }
            if (home.Torque2 > 0)
            {
                home.Torque2Result = "OK";

            }
            #endregion


            #region 加载风机，泄露值
            //心跳写入
            //DbHelper.LogTip("心跳写入");
            //services.plc.Write($"DB{Fields.DbAddr}.DBX{Fields.Map["HeartBeat"].First}.0", true);

            home.Fan.Voltage1 = Math.Round(plc.GetFloats[0], 2);
            home.Fan.Current1 = Math.Round(plc.GetFloats[1], 2);
            home.Fan.Frequency1 = Math.Round(plc.GetFloats[2], 2);
            home.Fan.Duty1 = Math.Round(plc.GetFloats[3], 2);
            home.Fan.ProgramNum1 = (int)plcData.Groups[0].ShowReal[0];

            //home.Fan.TestOK1 = GetResult((int)plc.GetFloats[4]) == "OK" ? true : false;
            if ((int)plc.GetFloats[4] == 0)
            {
                home.Fan.TestNG1 = false;
                home.Fan.TestOK1 = false;

            }
            else if ((int)plc.GetFloats[4] == 1)
            {
                home.Fan.TestNG1 = false;
                home.Fan.TestOK1 = true;

            }
            else
            {
                home.Fan.TestNG1 = true;
                home.Fan.TestOK1 = false;

            }

            // home.Fan.TestNG1 = GetResult((int)plc.GetFloats[4]) = "NG" ? true : false;
            home.Fan.Voltage2 = Math.Round(plc.GetFloats[5], 2);
            home.Fan.Current2 = Math.Round(plc.GetFloats[6], 2);
            home.Fan.Frequency2 = Math.Round(plc.GetFloats[7], 2);
            home.Fan.Duty2 = Math.Round(plc.GetFloats[8], 2);
            home.Fan.ProgramNum1 = (int)plcData.Groups[1].ShowReal[0];
            home.Fan.TestOK2 = GetResult((int)plc.GetFloats[9]) == "OK" ? true : false;
            home.Fan.TestNG2 = GetResult((int)plc.GetFloats[9]) == "NG" ? true : false;

            if ((int)plc.GetFloats[9] == 0)
            {
                home.Fan.TestNG2 = false;
                home.Fan.TestOK2 = false;

            }
            else if ((int)plc.GetFloats[9] == 1)
            {
                home.Fan.TestNG2 = false;
                home.Fan.TestOK2 = true;

            }
            else
            {
                home.Fan.TestNG2 = true;
                home.Fan.TestOK2 = false;

            }



            home.Leakage.Pressure = Math.Round(plc.GetFloats[10], 2);  //压力
            home.Leakage.LeakageVal = Math.Round(plc.GetFloats[11], 2); //泄露
            //home.Leakage.TestOK = GetResult((int)plc.GetFloats[12]) == "OK" ? true : false;
            //home.Leakage.TestNG = GetResult((int)plc.GetFloats[12]) == "NG" ? true : false;

            if ((int)plc.GetFloats[12] == 0)
            {
                home.Leakage.TestNG = false;
                home.Leakage.TestOK = false;

            }
            else if ((int)plc.GetFloats[12] == 1)
            {
                home.Leakage.TestNG = false;
                home.Leakage.TestOK = true;

            }
            else
            {
                home.Leakage.TestNG = true;
                home.Leakage.TestOK = false;

            }



            #endregion


            //home.ProModel = proSet.Products.Count > plc.ProduceModel && plc.ProduceModel > 0 ? proSet.Products[plc.ProduceModel] : string.Empty;            
            //home.ProModel = proSet.Products.Count > plc.LocalModelId ? proSet.Products[plc.LocalModelId] : string.Empty;
            #region 原有型号显示
          

             var ModelIndexList=proSet.ModelIndexs.Where(p=>p.Index==plc.LocalModelId).ToList();
            if (ModelIndexList.Count > 0)
            {
                home.ProModel = ModelIndexList.FirstOrDefault().Name;
            }
            else
            {
                home.ProModel = "";

            }

            //新型号与旧型号不同下发新型号的配置
            if (PastProModel != home.ProModel)
            {

                proSet.UpdateProductConfig(home.ProModel);
                PastProModel = home.ProModel;
            }

            #endregion 
            #region
            //if (home.ProModel==null)
            //{
            //    Thread.Sleep(3000);
            //    if (proSet.Products.Count > 0 && plc.LocalModelId == 0)
            //    {
            //        home.ProModel = proSet.Products[plc.LocalModelId];
            //    }
            //    if (proSet.Products.Count > 0 && plc.LocalModelId <= proSet.Products.Count && plc.LocalModelId != 0)
            //    {

            //        home.ProModel = proSet.Products[plc.LocalModelId - 1];
            //    }
            //}
            //else
            //{
            //    if (proSet.Products.Count > 0&& proSet.ProIndex>-1)
            //    {
            //        home.ProModel = proSet.Products[proSet.ProIndex];
            //    }
            //}
            #endregion
        }

        /// <summary>
        /// 风机采集步骤
        /// </summary>
        public float CollectionSteps = 0;

        /// <summary>
        /// 获取外部设备采集数据
        /// </summary>
        private void GetExDevData(PlcData plcData)
        {
            for (int i = 0; i < 4; i++)
            {
                if (serialPorts[i] != null)
                {
                    //扫码
                    if (serialPorts[i].SerialType == "Scan" && serialPorts[i].IsOpen)
                    {
                        serialPorts[i].IsEnable = home.EnablScan;
                        if (!string.IsNullOrEmpty(serialPorts[i].ScanCode))
                        {
                            home.ScanCode = serialPorts[i].ScanCode;

                            serialPorts[i].ScanCode = string.Empty;
                        }

                    }
                    //风机1
                    if (serialPorts[i].SerialType == "Fan1" && serialPorts[i].IsOpen)
                    {
                        serialPorts[i].ProgramNumber = (int)plcData.Groups[0].ShowReal[0];
                        serialPorts[i].step = (int)plcData.Groups[0].ShowReal[1];
                        serialPorts[i].CollectionSteps = CollectionSteps;

                    }
                    //风机2
                    if (serialPorts[i].SerialType == "Fan2" && serialPorts[i].IsOpen)
                    {

                        serialPorts[i].ProgramNumber = (int)plcData.Groups[1].ShowReal[0];
                        serialPorts[i].step = (int)plcData.Groups[1].ShowReal[1];
                        serialPorts[i].CollectionSteps = CollectionSteps;
                    }
                }
            }
        }
        /// <summary>
        /// 重置采集数据、扫码状态
        /// </summary>
        public void ResetCollection()
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                home.PartCodes.Clear();
                home.RepeatCode = string.Empty;
                photoDev.PhotoNum = 0;
                foreach (var item in proSet.EnableScans)
                {
                    item.IsScan = false;
                }
            });
        }

        private void RefreshIO(PlcData plc)
        {
            try
            {


                for (int i = 0; i < IO.DisplayInputs.Count; i++)
                {

                    if (i < 16)
                    {
                        IO.DisplayInputs[i].IsOn = Convert.ToBoolean(Locator.Instance.Service.plc.Read(IO.DisplayInputs[i].SignalName));
                    }

                }
                for (int i = 0; i < IO.DisplayOutputs.Count; i++)
                {

                    if (i < 16)
                    {
                        //IO.DisplayOutputs[i].IsOn = plc.Out[i];
                        IO.DisplayOutputs[i].IsOn = Convert.ToBoolean(Locator.Instance.Service.plc.Read(IO.DisplayOutputs[i].SignalName));
                    }
                }
            }
            catch (Exception ex)
            {


            }
        }
        private void RefreshManual(PlcData plc)
        {
            //气缸1
            //Manual.Forward1 = Read(1) ? plc.Manual[1] : false;
            //Manual.ForwardArrived1 = Read(1) ? plc.Manual[2] : false;
            //Manual.ForwardSafety1 = Read(1) ? plc.Manual[3] : false;
            //Manual.Backward1 = Read(1) ? plc.Manual[5] : false;
            //Manual.BackwardArrived1 = Read(1) ? plc.Manual[6] : false;
            //Manual.BackwardSafety1 = Read(1) ? plc.Manual[7] : false;
            Manual.Forward1 = plc.Manual[1];
            Manual.ForwardArrived1 = plc.Manual[2];
            Manual.ForwardSafety1 = plc.Manual[3];
            Manual.Backward1 = plc.Manual[5];
            Manual.BackwardArrived1 = plc.Manual[6];
            Manual.BackwardSafety1 = plc.Manual[7];
            //气缸2
            //Manual.Forward2 = Read(2) ? plc.Manual[9] : false;
            //Manual.ForwardArrived2 = Read(2) ? plc.Manual[10] : false;
            //Manual.ForwardSafety2 = Read(2) ? plc.Manual[11] : false;
            //Manual.Backward2 = Read(2) ? plc.Manual[13] : false;
            //Manual.BackwardArrived2 = Read(2) ? plc.Manual[14] : false;
            //Manual.BackwardSafety2 = Read(2) ? plc.Manual[15] : false;
            Manual.Forward2 = plc.Manual[9];
            Manual.ForwardArrived2 = plc.Manual[10];
            Manual.ForwardSafety2 = plc.Manual[11];
            Manual.Backward2 = plc.Manual[13];
            Manual.BackwardArrived2 = plc.Manual[14];
            Manual.BackwardSafety2 = plc.Manual[15];
            //气缸3
            //Manual.Forward3 = Read(3) ? plc.Manual[17] : false;
            //Manual.ForwardArrived3 = Read(3) ? plc.Manual[18] : false;
            //Manual.ForwardSafety3 = Read(3) ? plc.Manual[19] : false;
            //Manual.Backward3 = Read(3) ? plc.Manual[21] : false;
            //Manual.BackwardArrived3 = Read(3) ? plc.Manual[22] : false;
            //Manual.BackwardSafety3 = Read(3) ? plc.Manual[23] : false;
            Manual.Forward3 = plc.Manual[17];
            Manual.ForwardArrived3 = plc.Manual[18];
            Manual.ForwardSafety3 = plc.Manual[19];
            Manual.Backward3 = plc.Manual[21];
            Manual.BackwardArrived3 = plc.Manual[22];
            Manual.BackwardSafety3 = plc.Manual[23];
            //气缸4
            //Manual.Forward4 = Read(4) ? plc.Manual[25] : false;
            //Manual.ForwardArrived4 = Read(4) ? plc.Manual[26] : false;
            //Manual.ForwardSafety4 = Read(4) ? plc.Manual[27] : false;
            //Manual.Backward4 = Read(4) ? plc.Manual[29] : false;
            //Manual.BackwardArrived4 = Read(4) ? plc.Manual[30] : false;
            //Manual.BackwardSafety4 = Read(4) ? plc.Manual[31] : false;

            Manual.Forward4 = plc.Manual[25];
            Manual.ForwardArrived4 = plc.Manual[26];
            Manual.ForwardSafety4 = plc.Manual[27];
            Manual.Backward4 = plc.Manual[29];
            Manual.BackwardArrived4 = plc.Manual[30];
            Manual.BackwardSafety4 = plc.Manual[31];


            //气缸5
            Manual.Forward5 = Read(5) ? plc.Manual[33] : false;
            Manual.ForwardArrived5 = Read(5) ? plc.Manual[34] : false;
            Manual.ForwardSafety5 = Read(5) ? plc.Manual[35] : false;
            Manual.Backward5 = Read(5) ? plc.Manual[37] : false;
            Manual.BackwardArrived5 = Read(5) ? plc.Manual[38] : false;
            Manual.BackwardSafety5 = Read(5) ? plc.Manual[39] : false;
        }
        private bool Read(int index)
        {
            return Manual.ReadStatus == index || Manual.ReadStatus == 0;
        }
        private string GetResult(int checkVal)
        {
            string result = string.Empty;
            switch (checkVal)
            {
                case 1: result = "OK"; break;
                case 2: result = "NG"; break;
                case 3: result = "OK(Artificial)"; break;
                default: result = "NG"; break;
            }
            return result;
        }
        #endregion
    }
}
